<?php

namespace app\common\component;

use think\Config;
use Elasticsearch\ClientBuilder;

/**
 * elasticsearch api操作基累
 * Class Elasticsearch
 * @package app\common\component
 */
class Elasticsearch
{
    /** @var null 单例实体 */
    protected static $instance = null;
    /** @var \Elasticsearch\Client|null 连接客户端 */
    protected static $client = null;

    private function __construct()
    {
        if (is_null(self::$client)) {
            $hosts = [
                Config::get('elasticsearch.bind') . ':' . Config::get('elasticsearch.port')
            ];

            $clientBuilder = ClientBuilder::create();         // 实例化 ClientBuilder
            $clientBuilder->setHosts($hosts);                 // 设置主机信息
            self::$client = $clientBuilder->build();          // 构建客户端对象
        }
    }

    /**
     * 单例
     * @param bool $newInstance
     * @return Elasticsearch|null
     */
    public static function getInstance($newInstance = false)
    {
        if (is_null(static::$instance) || $newInstance) {
            self::$instance = new self();
        }

        return self::$instance;
    }

    /**
     * 添加elasticsearch数据
     * @param $index
     * @param $type
     * @param $data
     * @throws \Exception
     */
    public function add($index, $type, $data)
    {
        $data = [
            'index' => $index,
            'type' => $type,
            'id' => $data['id'],
            'body' => $data
        ];

        $response = self::$client->index($data);
        if (!isset($response['_id'])) {
            throw new \Exception('添加elasticsearch索引失败', ErrorCode::RESPONSE_FAIL);
        }
    }

    /**
     * 删除数据
     * @param $index
     * @param $type
     * @param $id
     * @throws \Exception
     */
    public function delete($index, $type, $id)
    {
        $params = [
            'index' => $index,
            'type' => $type,
            'id' => $id
        ];

        try {
            $response = self::$client->delete($params);
            if (!isset($response['result']) && $response['result'] == 'deleted') {
                throw new \Exception('删除elasticsearch索引失败', ErrorCode::RESPONSE_FAIL);
            }
        } catch (\Exception $e) {
            throw new \Exception('删除elasticsearch索引失败', ErrorCode::RESPONSE_FAIL);
        }
    }

    /**
     * 热词
     * @return array
     */
    public function hotPhrase()
    {
        $params = [
            'index' => 'www',
            'type' => 'practice',
            'body' => [
                'query' => [
                    'match_phrase' => [
                        'ela_identify' => Param::$validParams['ela_identify']
                    ]
                ],
                'aggs' => [
                    'hot_word' => [
                        'terms' => [
                            "field" => 'content',
                            "size" => 100
                        ]
                    ]
                ]
            ]
        ];

        $results = self::$client->search($params);
        $data = [];
        if (isset($results['aggregations']['hot_word']['buckets'])) {
            foreach ($results['aggregations']['hot_word']['buckets'] as $item) {
                if (mb_strlen($item['key'], 'utf-8') >= 2) {
                    $data[] = $item;
                }
            }
        }

        return $data;
    }
}